package com.sxhuayuan.parking.service.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.sxhuayuan.parking.compenent.Filter;
import com.sxhuayuan.parking.compenent.Page;
import com.sxhuayuan.parking.compenent.Pageable;
import com.sxhuayuan.parking.config.CarActType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.sxhuayuan.parking.dao.BaseDao;
import com.sxhuayuan.parking.dao.OrderDao;
import com.sxhuayuan.parking.dao.ParkingInDao;
import com.sxhuayuan.parking.entity.ParkingIn;
import com.sxhuayuan.parking.entity.ParkingLot;
import com.sxhuayuan.parking.service.ParkingInOutService;
import com.sxhuayuan.parking.service.ParkingInService;
import com.sxhuayuan.parking.utils.DateUtils;
import com.sxhuayuan.parking.utils.SnowFlake;

@Service("parkingInServiceImpl")
public class ParkingInServiceImpl extends BaseServiceImpl<ParkingIn, Long> implements ParkingInService {

	Logger log = LoggerFactory.getLogger(getClass());

	@Resource
	ParkingInDao dao;
	@Resource
	OrderDao orderDao;
	@Resource
	ParkingInOutService outService;
	@Resource(name = "orderNoFactory")
	SnowFlake orderNoFactory;

	@Override
	public BaseDao<ParkingIn, Long> getDAO() {
		return dao;
	}

	@Override
	public ParkingIn enter(ParkingLot lot, String carPlate, Date time, Long channelId, Integer freeMinutes, CarActType carActType) {
		return enter(lot, carPlate, time, channelId, freeMinutes, "", carActType);
	}

	@Override
	public ParkingIn enter(ParkingLot lot, String carPlate, Date time, Long channelId, Integer freeMinutes, String lotRecordId, CarActType carActType) {
		Assert.notNull(lot, "");
		Assert.notNull(carPlate, "");
		ParkingIn in = dao.findByCarPlateAndParkingLotId(carPlate, lot.getId());
		if (in != null) {
			long diff = DateUtils.diff(time, in.getInTime(), Calendar.SECOND);
			if (diff < 0) {
				log.debug("存在过期入场记录，删除{}", in.getInTime());
				orderDao.deleteByUniqueId(in.getUniqueId());
				dao.delete(in);
			} else if (diff > 0) {
				log.warn("新的入场时间大于记录的入场时间，将原入场记录作出场处理: {}", in.getUniqueId());
				outService.out(in, DateUtils.add(in.getInTime(), Calendar.SECOND, -1), null);
			} else {
				return in;
			}
		}
		in = new ParkingIn();
		in.setCarPlate(carPlate);
		in.setEntranceId(channelId);
		in.setParkingLotId(lot.getId());
		in.setInTime(time == null ? new Date() : time);
		in.setUniqueId(orderNoFactory.nextId());
		in.setFreeMinutes(freeMinutes);
		in.setLotRecordId(lotRecordId);
		in.setLastChargeTime(null);
		in.setCarActType(carActType == null ? CarActType.temporary : carActType);
		dao.save(in);
		return in;
	}

	@Override
	public ParkingIn findByCarPlate(Long parkingLotId, String carPlate) {
		return dao.findByCarPlateAndParkingLotId(carPlate, parkingLotId);
	}

	@Override
	public ParkingIn findByUniqueId(Long uniqueId) {
		return dao.findByUniqueId(uniqueId);
	}

	@Override
	public ParkingIn findByParkingLotIdAndLotRecordId(Long lotId, String recordId) {
		return dao.findByParkingLotIdAndLotRecordId(lotId, recordId);
	}

	@Override
	public Page<ParkingIn> findByPage(Pageable pageable) {
		Assert.notNull(pageable, "pageable不能为空");
		StringBuilder sb = new StringBuilder();
		List<Filter> filters = pageable.getFilters();
		boolean isParkingName = false;
		if (filters != null) {
			for (Filter filter : filters) {
				if ("parkingLotName".equals(filter.getProperty())) {
					isParkingName = true;
				}
				setCondition(sb, filter);
			}
		}

		if (isParkingName) {
			sb.insert(0, "select pi from ParkingIn pi left join ParkingLot p on pi.parkingLotId=p.id where 1=1 ");
		} else {
			sb.insert(0, "select pi from ParkingIn pi where 1=1 ");
		}
		sb.append(" order by pi.inTime desc");
		return findPage(sb.toString(), sb.toString().replace("select pi", "select count(pi.id)"), pageable.getPageSize(), pageable.getPageNumber());
	}

	/** 组装查询条件 */
	private void setCondition(StringBuilder sb, Filter filter) {
		if (filter.getProperty() == null || "".equals(filter.getProperty()) || filter.getValue() == null || "".equals(filter.getValue())) {
			return;
		}
		switch (filter.getProperty()) {
		case "istartTime": {// 入场开始时间
			sb.append(" and pi.inTime>='").append(filter.getValue()).append("' ");
			break;
		}
		case "iendTime": {// 入场结束时间
			sb.append(" and pi.inTime<='").append(filter.getValue()).append("' ");
			break;
		}
		case "parkingLotName": {// 车场名称
			sb.append(" and p.name='").append(filter.getValue()).append("' ");
			break;
		}
		case "carPlate": {// 车牌号
			sb.append(" and pi.carPlate='").append(filter.getValue()).append("' ");
			break;
		}
		case "entranceId": {// 入口id
			sb.append(" and pi.entranceId='").append(filter.getValue()).append("' ");
			break;
		}
		case "uniqueId": {// 唯一编号
			sb.append(" and pi.uniqueId=").append(filter.getValue()).append(" ");
			break;
		}
		default:
		}
	}
}
